home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 7 / Night Owl Shareware (NOPV7)(Night Owl Publisher Inc.)(1992).bin / 038a / bash1_12.arj / BASH1-12.TAR / bash-1.12 / nojobs.c < prev    next >
C/C++ Source or Header  |  1992-01-20  |  9KB  |  395 lines

  1. /* The thing that makes children, remembers them, and contains wait loops. */
  2.  
  3. /* This file works under BSD, System V, minix, and Posix systems. */
  4.  
  5. /* Copyright (C) 1987,1989 Free Software Foundation, Inc.
  6.  
  7. This file is part of GNU Bash, the Bourne Again SHell.
  8.  
  9. Bash is free software; you can redistribute it and/or modify it under
  10. the terms of the GNU General Public License as published by the Free
  11. Software Foundation; either version 1, or (at your option) any later
  12. version.
  13.  
  14. Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  15. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  17. for more details.
  18.  
  19. You should have received a copy of the GNU General Public License along
  20. with Bash; see the file COPYING.  If not, write to the Free Software
  21. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  22.  
  23. #include <stdio.h>
  24. #include <sys/types.h>
  25. #include <signal.h>
  26. #include <setjmp.h>
  27. #include <errno.h>
  28.  
  29. #include "config.h"
  30. #include "general.h"
  31. #include "filecntl.h"
  32. #include "jobs.h"
  33.  
  34. #if !defined (USG) && !defined (_POSIX_VERSION)
  35. #  include <sgtty.h>
  36. #else
  37. #  if defined (_POSIX_VERSION)
  38. #    include <termios.h>
  39. #  else
  40. #    include <termio.h>
  41. #    include <sys/ttold.h>
  42. #  endif /* !POSIX_VERSION */
  43. #endif /* USG && _POSIX_VERSION */
  44.  
  45. #if !defined (SIGABRT)
  46. #  define SIGABRT SIGIOT
  47. #endif /* !SIGABRT */
  48.  
  49. #if defined (USG) || defined (_POSIX_VERSION)
  50. #  define killpg(pg, sig)        kill(-(pg),(sig))
  51. #endif /* USG || _POSIX_VERSION */
  52.  
  53. #if defined (USG)
  54. #  define siginterrupt(sig, code)
  55. #endif /* USG */
  56.  
  57. #if defned (_POSIX_VERSION)
  58. #  define WAITPID(pid, statusp, options) waitpid (pid, statusp, options)
  59. #else
  60. #  define WAITPID(pid, statusp, options) wait (statusp)
  61. #endif /* !_POSIX_VERSION */
  62.  
  63. pid_t last_made_pid = (pid_t)-1;
  64. pid_t last_asynchronous_pid = (pid_t)-1;
  65.  
  66. extern int errno;
  67.  
  68. /* Initialize the job control mechanism, and set up the tty stuff. */
  69. initialize_jobs ()
  70. {
  71.   get_tty_state ();
  72. }
  73.  
  74. /* Setup this shell to handle C-C, etc. */
  75. initialize_job_signals ()
  76. {
  77.   extern int login_shell;
  78.   extern sighandler sigint_sighandler ();
  79.  
  80.   signal (SIGINT, sigint_sighandler);
  81.  
  82.   /* If this is a login shell we don't wish to be disturbed by
  83.      stop signals. */
  84.   if (login_shell)
  85.     {
  86. #ifdef SIGTSTP
  87.       signal (SIGTSTP, SIG_IGN);
  88.       signal (SIGTTOU, SIG_IGN);
  89.       signal (SIGTTIN, SIG_IGN);
  90. #endif
  91.     }
  92. }
  93.  
  94. #if defined (_POSIX_VERSION)
  95. /* Collect the status of all zombie children so that their system
  96.    resources can be deallocated. */
  97. static void
  98. reap_zombie_children ()
  99. {
  100. #if defined (WNOHANG)
  101.   while (waitpid (-1, (int *)NULL, WNOHANG) != -1)
  102.     ;
  103. #endif /* WNOHANG */
  104. }
  105. #endif /* _POSIX_VERSION */
  106.  
  107. /* Fork, handling errors.  Returns the pid of the newly made child, or 0.
  108.    COMMAND is just for remembering the name of the command; we don't do
  109.    anything else with it.  ASYNC_P says what to do with the tty.  If
  110.    non-zero, then don't give it away. */
  111. pid_t
  112. make_child (command, async_p)
  113.      char *command;
  114.      int async_p;
  115. {
  116.   pid_t pid;
  117. #if defined (_POSIX_VERSION)
  118.   int retry = 1;
  119. #endif /* _POSIX_VERSION */
  120.  
  121.   /* Discard saved memory. */
  122.   if (command)  
  123.     free (command);
  124.  
  125.   /* Make new environment array if neccessary. */
  126.   maybe_make_export_env ();
  127.  
  128.   /* Create the child, handle severe errors. */
  129. #if defined (_POSIX_VERSION)
  130.   retry_fork:
  131. #endif /* _POSIX_VERSION */
  132.  
  133.   if ((pid = fork ()) < 0)
  134.     {
  135. #if defined (_POSIX_VERSION)
  136.       /* Posix systems with a non-blocking waitpid () system call available
  137.      get another chance after zombies are reaped. */
  138.       if (errno == EAGAIN && retry)
  139.     {
  140.       reap_zombie_chilren ();
  141.       retry = 0;
  142.       goto retry_fork;
  143.     }
  144. #endif /* _POSIX_VERSION */
  145.  
  146.       report_error ("fork: %s", strerror (errno));
  147.  
  148.       throw_to_top_level ();
  149.     }
  150.  
  151.   if (!pid)
  152.     {
  153.       /* Cancel shell traps. */
  154.       restore_original_signals ();
  155.  
  156.       /* Ignore INT and QUIT in asynchronous children. */
  157.       if (async_p)
  158.     {
  159.       signal (SIGINT, SIG_IGN);
  160.       signal (SIGQUIT, SIG_IGN);
  161.       last_asynchronous_pid = getpid ();
  162.     }
  163.       else
  164.     {
  165. #if defined (SIGTSTP)
  166.       signal (SIGTSTP, SIG_DFL);
  167.       signal (SIGTTIN, SIG_DFL);
  168.       signal (SIGTTOU, SIG_DFL);
  169. #endif
  170.     }
  171.     }
  172.   else
  173.     {
  174.       /* In the parent. */
  175.       last_made_pid = pid;
  176.  
  177.       if (async_p)
  178.     last_asynchronous_pid = pid;
  179.     }
  180.   return (pid);
  181. }
  182.  
  183. /* Wait for a single pid (PID) and return its exit status. */
  184. wait_for_single_pid (pid)
  185.      pid_t pid;
  186. {
  187.   pid_t got_pid;
  188.   WAIT status;
  189.  
  190.   /* Make sure that the process we are waiting for is valid. This
  191.      check is not necessary on Posix systems. */
  192. #if !defined (_POSIX_VERSION)
  193.   if ((kill (pid, 0) < 0) && errno == ESRCH)
  194.     return (127);
  195. #endif /* !_POSIX_VERSION */
  196.  
  197.   siginterrupt (SIGINT, 1);
  198.   while ((got_pid = WAITPID (pid, &status, 0)) != pid)
  199.     {
  200.       if (got_pid < 0)
  201.     {
  202.       if (errno != EINTR && errno != ECHILD)
  203.         {
  204.           siginterrupt (SIGINT, 0);
  205.           file_error ("wait");
  206.         }
  207.       break;
  208.     }
  209.     }
  210.   siginterrupt (SIGINT, 0);
  211.   QUIT;
  212. }
  213.  
  214. /* Wait for all of the shell's children to exit. */
  215. wait_for_background_pids ()
  216. {
  217.   /* If we aren't using job control, we let the kernel take care of the
  218.      bookkeeping for us.  wait () will return -1 and set errno to ECHILD 
  219.      when there are no more unwaited-for child processes on both
  220.      4.2 BSD-based and System V-based systems. */
  221.  
  222.   siginterrupt (SIGINT, 1);
  223.   while (1)
  224.     {
  225.       pid_t got_pid;
  226.       WAIT status;
  227.  
  228.       /* Wait for ECHILD */
  229.       while ((got_pid = WAITPID (-1, &status, 0)) != -1)
  230.     ;
  231.       if (errno != EINTR && errno != ECHILD)
  232.     {
  233.       siginterrupt (SIGINT, 0);
  234.       file_error("wait");
  235.     }
  236.       break;
  237.     }
  238.   siginterrupt (SIGINT, 0);
  239.   QUIT;
  240. }
  241.  
  242. /* Wait for pid (one of our children) to terminate. */
  243. int
  244. wait_for (pid)
  245.      pid_t pid;
  246. {
  247.   extern int interactive;
  248.   int return_val;
  249.   pid_t got_pid;
  250.   WAIT status;
  251.  
  252.   /* Make sure that the process we are waiting for is valid.  This check
  253.      is not necessary on Posix systems. */
  254. #if !defined (_POSIX_VERSION)
  255.   if ((kill (pid, 0) < 0) && (errno == ESRCH))
  256.     return (0);
  257. #endif /* !_POSIX_VERSION */
  258.  
  259.   siginterrupt (SIGINT, 1);
  260.   while ((got_pid = WAITPID (pid, &status, 0)) != pid)
  261.     {
  262.       if (got_pid < 0 && errno == ECHILD)
  263.     {
  264. #if !defined (_POSIX_VERSION)
  265.       status.w_termsig = status.w_retcode = 0;
  266. #else
  267.       status = 0;
  268. #endif /* _POSIX_VERSION */
  269.       break;
  270.     }
  271.       else if (got_pid < 0 && errno != EINTR)
  272.     programming_error ("got errno %d while waiting for %d", errno, pid);
  273.     }
  274.   siginterrupt (SIGINT, 0);
  275.  
  276.   /* Default return value. */
  277.   /* ``a full 8 bits of status is returned'' */
  278.   if (WIFSIGNALED (status))
  279.     return_val = 128 + WTERMSIG (status);
  280.   else
  281.     return_val = WEXITSTATUS (status);
  282.                             
  283.   if (!WIFSTOPPED (status) && WIFSIGNALED (status) &&
  284.       (WTERMSIG (status) != SIGINT))
  285.     {
  286.       extern char *sys_siglist[];
  287.       fprintf (stderr, "%s", sys_siglist[WTERMSIG (status)]);
  288.       if (WIFCORED (status))
  289.     fprintf (stderr, " (core dumped)");
  290.       fprintf (stderr, "\n");
  291.     }
  292.  
  293.   if (WIFSIGNALED (status) || WIFSTOPPED (status))
  294.     set_tty_state ();
  295.   else
  296.     get_tty_state ();
  297.                             
  298.   return (return_val);
  299. }
  300.  
  301. /* Give PID SIGNAL.  This determines what job the pid belongs to (if any).
  302.    If PID does belong to a job, and the job is stopped, then CONTinue the
  303.    job after giving it SIGNAL.  Returns -1 on failure.  If GROUP is non-null,
  304.    then kill the process group associated with PID. */
  305. int
  306. kill_pid (pid, signal, group)
  307.      pid_t pid;
  308.      int signal, group;
  309. {
  310.   int result;
  311.  
  312.   if (group)
  313.     result = killpg (pid, signal);
  314.   else
  315.     result = kill (pid, signal);
  316.  
  317.   return (result);
  318. }
  319.  
  320. #if defined (_POSIX_VERSION)
  321. static struct termios shell_tty_info;
  322. #else
  323. #  if defined (USG)
  324. static struct termio shell_tty_info;
  325. #  else
  326. static struct sgttyb shell_tty_info;
  327. #  endif /* USG */
  328. #endif /* _POSIX_VERSION */
  329.  
  330. static int got_tty_state = 0;
  331.  
  332. /* Fill the contents of shell_tty_info with the current tty info. */
  333. get_tty_state ()
  334. {
  335.   int tty = open ("/dev/tty", O_RDONLY);
  336.   if (tty != -1)
  337.     {
  338. #if defined (_POSIX_VERSION)
  339.       tcgetattr (tty, &shell_tty_info);
  340. #else
  341. #  if defined (USG)
  342.       ioctl (tty, TCGETA, &shell_tty_info);
  343. #  else
  344.       ioctl (tty, TIOCGETP, &shell_tty_info);
  345. #  endif
  346. #endif
  347.       close (tty);
  348.       got_tty_state = 1;
  349.     }
  350. }
  351.  
  352. /* Make the current tty use the state in shell_tty_info. */
  353. set_tty_state ()
  354. {
  355.   int tty = open ("/dev/tty", O_RDONLY);
  356.   if (tty != -1)
  357.     {
  358.       if (!got_tty_state)
  359.     {
  360.       close (tty);
  361.       return;
  362.     }
  363. #if defined (_POSIX_VERSION)
  364.       tcsetattr (tty, TCSADRAIN, &shell_tty_info);
  365. #else
  366. #  if defined (USG)
  367.       ioctl (tty, TCSETAW, &shell_tty_info);  /* Wait for output, no flush */
  368. #  else
  369.       ioctl (tty, TIOCSETN, &shell_tty_info);
  370. #  endif
  371. #endif
  372.       close (tty);
  373.     }
  374. }
  375.  
  376. /* Give the terminal to PGRP.  */
  377. give_terminal_to (pgrp)
  378.      pid_t pgrp;
  379. {
  380. }
  381.  
  382. /* Stop a pipeline. */
  383. stop_pipeline (async, ignore)
  384.      int async;
  385.      char *ignore;
  386. {
  387. }
  388.  
  389. /* Print descriptive information about the job with leader pid PID. */
  390. describe_pid (pid)
  391.      pid_t pid;
  392. {
  393.   fprintf (stderr, "<%d>\n", (int) pid);
  394. }
  395.